﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Reflection;

namespace OpenCube.Nbt.Mapping.Converters
{
	public sealed class NestedConverter<TModel>
		: INbtTypeConverter
		where TModel : class, new()
	{
		private readonly INbtMapperFactory _mapperFactory;

		public NestedConverter(INbtMapperFactory mapperFactory)
		{
			Contract.Requires<ArgumentNullException>(mapperFactory != null);
			_mapperFactory = mapperFactory;
		}

		public bool CanConvertToNbt(Type sourceModel)
		{
			throw new NotImplementedException();
		}

		public bool CanConvertToModel(IReadOnlyList<Type> sourceNbtTypes, Type targetModelType)
		{
			return sourceNbtTypes.Count == 1
				&& typeof(INbtDictionary).GetTypeInfo().IsAssignableFrom(sourceNbtTypes[0].GetTypeInfo())
				&& targetModelType != typeof(string) && targetModelType.GetTypeInfo().IsClass;
		}

		public object ConvertToModelValue(IConversionContext conversionContext, IReadOnlyList<object> nbtValue)
		{
			var mapper = _mapperFactory.Create<TModel>();
			return mapper.MapToModel((INbtDictionary)nbtValue[0]);
		}

		public IEnumerable<object> ConvertToNbtValue(IConversionContext conversionContext, object modelValue)
		{
			throw new NotImplementedException();
		}
	}
}
